package org.laobai.permission.service.impl;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.laobai.permission.entity.User;
import org.laobai.permission.entity.UserRole;
import org.laobai.permission.mapper.UserMapper;
import org.laobai.permission.service.UserRoleService;
import org.laobai.permission.service.UserService;
import org.laobai.permission.struct.PageResult;
import org.laobai.permission.util.Asserts;
import org.laobai.permission.util.JsonUtils;
import org.laobai.permission.util.JwtUtils;
import org.laobai.permission.vo.SearchVO;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

import java.util.ArrayList;
import java.util.Objects;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author jiusan
 * @since 2021-11-17
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Autowired
    private UserRoleService userRoleService;

    @Autowired
    private JwtUtils jwtUtils;

    @Override
    public PageResult<User> page(Integer currPage, Integer pageSize, SearchVO vo) {
        // 分页
        Page<User> userPage = new Page<>(currPage, pageSize);

        // 条件查询
        QueryWrapper<User> wrapper = new QueryWrapper<>();

        if (Objects.nonNull(vo)) {
            String keyWord = vo.getKeyWord();
            if (!StringUtils.isEmpty(keyWord)) {
                wrapper.like("a.name", keyWord);
            }
        }

        userPage = baseMapper.getPage(userPage, wrapper);
        return PageResult.of(userPage.getRecords(), userPage.getTotal());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveUser(User user) {
        // 校验用户
        Asserts.isNotNull(user.getName(), 40001, "用户名胃不空");

        // 先处理基础信息
        user.setPassword("123456");
        // 保证用户名唯一
        // TODO

        // 先保存主表
        boolean save = save(user);
        // 保存中间表
        saveMiddle(user);

        return save;
    }

    /**
     * 保存中间表
     * @param user
     */
    private void saveMiddle(User user) {
        List<Integer> rids = user.getRids();
        if (!CollectionUtils.isEmpty(rids)) {
            Integer uid = user.getId();
            List<UserRole> data = new ArrayList<>();
            rids.forEach(item -> {
                data.add(new UserRole(uid, item));
            });
            userRoleService.saveBatch(data);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateUser(User user) {
        // 删除中间表
        userRoleService.remove(new QueryWrapper<UserRole>().eq("uid",user.getId()));
        // 添加中间表
        saveMiddle(user);
        // 修改主表
        return updateById(user);
    }

    @Override
    public boolean delById(Long id) {
        return removeById(id);
    }

    @Override
    public boolean delByIds(List<Long> ids) {
        return removeByIds(ids);
    }

    @Override
    public List<Integer> getRidsByUid(Long id) {
        List<UserRole> list = userRoleService.list(new QueryWrapper<UserRole>().eq("uid", id));
        if (CollectionUtils.isEmpty(list)) {
            return new ArrayList<>();
        }
        return list.stream().map(UserRole::getRid).collect(Collectors.toList());
    }

    @Override
    public User login(User user) {
        /**
         * 1、根据用户名查询
         * 2、比较密码
         * 3、信息存储
         */
        //根据用户名查询
        Asserts.assertTrue(Objects.nonNull(user), 50001, "登录信息参数有误");

        User userDB = getOne(new QueryWrapper<User>().eq("username", user.getUsername()));
        //比较密码
        Asserts.assertTrue(Objects.nonNull(userDB), 50002, "用户名密码有问题");
        Asserts.assertTrue(userDB.getPassword().equals(user.getPassword()), 50002, "用户名密码有问题");
        Asserts.assertTrue(userDB.getEnabled(), 50003, "账户已冻结，请联系管理员桑");


        // 生成token
        userDB.setToken(jwtUtils.createToken(JsonUtils.objectToJson(userDB)));

        // 密码
        userDB.setPassword(null);

        return userDB;
    }
}
